/*
 * DefaultCalendarModel.java
 *
 * Created on 7-Mar-2010.
 */

package org.calendar;

import org.calendar.event.CalendarModelListener;
import org.calendar.event.ModelChangedEvent;
import javax.swing.event.EventListenerList;
import java.util.Calendar;
import java.util.Locale;
import java.util.Date;


/**
 * This class is the model used by MyCalendar.
 * Each component of org.calendar after being added as a registered
 * listener by the method <code> addCalendarModelListener</code>
 * listen to the model change.
 *
 * @see org.calendar.event.ModelChangedEvent
 * @see org.calendar.event.CalendarModelListener
 * @see org.calendar.JCalendar
 * @see org.calendar.JDaySelector
 * @see org.calendar.JMonthNavigator
 *
 * @author Julie Duvillier
 */

public class DefaultCalendarModel {

    /** Model Listener list */
    private EventListenerList listenersList;

    /** Calendar to be displayed */
    private Calendar calToDisplay ;

    private Locale locale;

    /**
     * Create a new Calendar Model
     */
    public DefaultCalendarModel(){
        this( Calendar.getInstance() );
    }

    /**
     * Create a new Calendar model with a  given calendar
     * @param calendar the calendar to display
     */
    public DefaultCalendarModel(Calendar calendar){
        this(calendar,
             Locale.getDefault() );
    }

    /**
     * Create a new Calendar model with a given calendar and locale
     *
     * @param calendar the calendar to display
     * @param locale the locale to use
     */
    public DefaultCalendarModel(Calendar calendar, Locale locale){
        Date date;  // date to display
        
        calToDisplay  = (Calendar)calendar.clone();
        this.locale = locale;
        date = calToDisplay .getTime();    // Extract the date
        calToDisplay = Calendar.getInstance(this.locale);
        calToDisplay.setTime(date);        //reset to the correct date

        listenersList = new EventListenerList();
    }

    /**
     * Gets the calendar to display
     * @return the calendar to display
     */
    public Calendar getCalendarToDisplay(){
        return (Calendar)calToDisplay.clone();
    }

    /**
     * Gets the locale
     * @return the locale value
     */
    public Locale getLocale(){
        return locale;
    }

    /**
     * Sets the calendar to be displayed.
     * It fire a calendar model changed
     * @param calendar new calendar to be displayed
     */
    public void setCalendarToDisplay(Calendar calendar){
        calToDisplay = (Calendar)calendar.clone();
        fireCalendarToDisplayChanged();
    }

    /**
     * Sets the locale.
     * Update the calendar to be displayed with the new
     * locale value and fire a calendar model changed event.
     * @param locale the new locale value
     */
    public void setLocale(Locale locale){
         Date date;  // hold the date to display

         if( locale != null){
             this.locale = locale;
         } else {
             this.locale = Locale.getDefault();
         }
         
         date = calToDisplay.getTime();    // Extract the date
         calToDisplay = Calendar.getInstance( this.locale );
         calToDisplay.setTime(date);        //reset to the correct date

         setCalendarToDisplay(calToDisplay);
    }


    /**
     * This method is invoked when the calendar or locale been set.
     * It creates a new <code>ModelChangedEvent</code> holding the new 
     * calendar to display and locale informations.
     * It then invokes listeners' method <code>calendarModelChanged</code>
     */
    private void fireCalendarToDisplayChanged(){
        CalendarModelListener[] listeners;  // array of model listeners
        ModelChangedEvent event;            // a model changed event

        listeners = listenersList.getListeners(CalendarModelListener.class);
        event = new ModelChangedEvent( this, getCalendarToDisplay(), getLocale() );

        for(int i = listeners.length -1; i>=0; --i){
            listeners[i].calendarModelChanged( event );
        }
    }

    /**
     * Add a given listener to the model changes listener list
     * @param listener the listener to be added to the list.
     */
    public void addCalendarModelListener(CalendarModelListener listener){
        listenersList.add(CalendarModelListener.class, listener);
    }

    /**
     * Removes a given listener to the model changes listener list
     * @param listener the listener to be removed from the list.
     */
    public void removeCalendarModelListener(CalendarModelListener listener){
        if( listenersList != null ){
            listenersList.remove(CalendarModelListener.class, listener);
        }
    }


}
